﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WpfFootball.Parser;
using System.Threading;
#endregion

namespace WpfFootball.UI
{
    /// <summary>
    /// Interaction logic for UpcomingFixturesView.xaml
    /// </summary>
    public partial class UpcomingFixturesView: UpdatableView
    {
        #region Fields
        private const int TEAM_TEXTBLOCK_WIDTH = 110;
        private const int TEAM_DELIMETER_WIDTH = 20;
        private const int DATE_TEXTBLOCK_WIDTH = 50;
        private const int STACKPANEL_WIDTH = 299;
        private const string DELIMETER_CHAR = "vs";

        private bool isUncheckingOther = false;
        private List<NextGameEntry> nextGames;
        #endregion
        
        public UpcomingFixturesView(string teamName)
        {
            this.teamName = teamName;          
            InitializeView();
            RegisterEventHandlers();
        }

        /// <summary>
        /// Initializes the components of this view.
        /// </summary>
        public override void InitializeView()
        {
            initializing = true;
            viewKind = ViewKind.FIXTURES;
            ioManager = IOManager.Instance();
            parser = new DataParser();
            InitializeComponent();
            ApplyViewSettings();
            BeginUpdate();
            ScaleUpViewAnimation();
            defaultViewHeight = this.Height;
            initializing = false;
        }

        /// <summary>
        /// Registers additional event handlers to this view.
        /// </summary>
        public override void RegisterEventHandlers()
        {
            base.RegisterEventHandlers();
            parser.ParseFixturesEntriesCompleted += FixtureEntriesParsed;
        }

        #region View Settings
        /// <summary>
        /// Revalidates the menu items of the context menu to match
        /// the settings for this view.
        /// </summary>
        public override void RevalidateContextMenu()
        {
            autoUpdateMenuItem.IsChecked = viewSettings.AutoUpdate;

            switch (viewSettings.UpdateFrequency)
            {
                case 2:
                    updtf2.IsChecked = true;
                    break;
                case 5:
                    updtf5.IsChecked = true;
                    break;
                case 10:
                    updtf10.IsChecked = true;
                    break;
                case 30:
                    updtf30.IsChecked = true;
                    break;
            }

            switch (viewSettings.EntryCounter)
            {
                case 2:
                    entr2.IsChecked = true;
                    break;
                case 4:
                    entr4.IsChecked = true;
                    break;
                case 6:
                    entr6.IsChecked = true;
                    break;
                case 8:
                    entr8.IsChecked = true;
                    break;
                case 10:
                    entr10.IsChecked = true;
                    break;
            }
        }

        /// <summary>
        /// Loads the settings for this view and applies those to this view.
        /// </summary>
        public override void ApplyViewSettings()
        {
            viewSettings = ioManager.GetViewSettings(teamName, viewKind);
            SetViewLocation();
            RevalidateContextMenu();
            RevalidateAutoUpdateThread();
        }

        #endregion      

        #region Auto Update Thread Handling
        /// <summary>
        /// Runs auto updating operations. This method is and
        /// should be called from another thread.
        /// </summary>
        public override void AutoUpdateThreadWorker()
        {
            while (true)
            {
                lock (viewSettings)
                {
                    Thread.Sleep(viewSettings.UpdateFrequency * 1000);
                }
                Console.WriteLine("Fixtures view updating every: " + viewSettings.UpdateFrequency);
                BeginUpdate();
            }
        }

        /// <summary>
        /// Checks the latest auto update setting status and based of that
        /// aborts or initializes the auto update thread.
        /// </summary>
        public override void RevalidateAutoUpdateThread()
        {
            if (viewSettings.AutoUpdate)
            {
                InitAutoUpdateThread();
            }
            else
            {
                AbortAutoUpdateThread();
            }
        }
        #endregion

        #region Update
        /// <summary>
        /// Atempts to update the view asynchronously.
        /// </summary>
        public void BeginUpdate()
        {
            RotateControl(0, 360, button2);
            parser.BeginParseNextGames(teamName, viewSettings.EntryCounter);
        }

        /// <summary>
        /// Updates the news current team, usually called when 
        /// the ParseFixturesEntriesCompleted event has been fired.
        /// </summary>
        public void Update()
        {
            stackPanel2.Dispatcher.BeginInvoke(
                new Action(() =>
                {
                    stackPanel2.Children.Clear();

                    foreach (NextGameEntry gameEntry in nextGames)
                    {
                        if (gameEntry != null)
                        {
                            Border border = new Border();
                            border.Style = (Style)this.FindResource("newsBorder");

                            StackPanel stackPanel = new StackPanel();
                            stackPanel.Style = (Style)this.FindResource("newsPanel");

                            TextBlock dateTextBlock = new TextBlock();
                            dateTextBlock.Style = (Style)this.FindResource("fixtureDateTextBlockStyle");
                            dateTextBlock.Text = gameEntry.timeStamp;

                            stackPanel.Children.Add(dateTextBlock);

                            StackPanel teamsStackPanel = new StackPanel();
                            teamsStackPanel.Style = (Style)this.FindResource("teamsPanelStyle");

                            TextBlock teamA = new TextBlock();
                            teamA.Style = (Style)this.FindResource("homeTeamTextBlockStyle");
                            teamA.Text = gameEntry.teamA;

                            TextBlock delimeter = new TextBlock();
                            delimeter.Style = (Style)this.FindResource("delimeterStyle");
                            delimeter.Text = DELIMETER_CHAR;

                            TextBlock teamB = new TextBlock();
                            teamB.Style = (Style)this.FindResource("visitTeamTextBlockStyle");
                            teamB.Text = gameEntry.teamB;

                            teamsStackPanel.Children.Add(teamA);
                            teamsStackPanel.Children.Add(delimeter);
                            teamsStackPanel.Children.Add(teamB);
                            stackPanel.Children.Add(teamsStackPanel);

                            border.Child = stackPanel;
                            stackPanel2.Children.Add(border);
                        }
                    }
                }));
        }
        #endregion

        #region Event Handlers
        private void FixtureEntriesParsed(object sender, FixturesEventArgs args)
        {
            nextGames = args.nextGames;
            StopControlRotation(button2);
            Update();
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            BeginUpdate();
        }

        private void button1_ContextMenuClosing(object sender, ContextMenuEventArgs e)
        {
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            settingsMenu.PlacementTarget = this;
            settingsMenu.IsOpen = true;
        }
        #endregion
    }
}
